﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace HuaJuanAudioNevolDown
{
    public partial class frmMain : Form
    {
        IExtractor extractor = null;
        Dictionary<string, IExtractor> extractors = null;

        private DataTable novelData = new DataTable();

        public frmMain()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            this.Text = "花卷有声小说下载器";

            btnDownByIdm.Enabled = false;
            btnSaveToFile.Enabled = false;

            // 提取后的数据的右键菜单功能
            ToolStripMenuItem menuItem1 = new ToolStripMenuItem("复制选中行到剪贴板");
            menuItem1.Click += MenuItem1_Click;

            ToolStripMenuItem menuItem2 = new ToolStripMenuItem("使用IDM下载选中行");
            menuItem2.Click += MenuItem2_Click;

            ToolStripMenuItem menuItem3 = new ToolStripMenuItem("重新提取失败地址");
            menuItem3.Click += MenuItem3_Click;

            contextMenuStrip1.Items.Add(menuItem1);
            contextMenuStrip1.Items.Add(menuItem2);
            contextMenuStrip1.Items.Add(menuItem3);

            // 初使化提取后数据Datatable
            InitializeDataTable();

            columnHeader5.Width = 150;
            columnHeader6.Width = 150;
            columnHeader7.Width = 150;
            columnHeader8.Width = 150;
            columnHeader9.Width = 150;

            extractors = Service.Instance.GetAllExtractors();

            this.BeginInvoke((Action)(() =>
            {
                txtKeyword.Focus();
            }));
        }

        private void MenuItem1_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                string url = "";
                string status = "";
                foreach (DataGridViewRow row in dataGridView1.SelectedRows)
                {
                    status = row.Cells["ExtractorStatus"].Value.ToString();
                    if (status == ExtractorStatus.Sucess.GetDescription())
                    {
                        url += row.Cells["RealAddress"].Value.ToString() + "\r\n";
                    }
                }
                if (string.IsNullOrEmpty(url))
                {
                    MessageBox.Show("选择的行中没有提取成功数据", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    Clipboard.SetText(url);
                    MessageBox.Show("复制完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void MenuItem2_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                string idm = Service.Instance.IDMPath;
                string args = "";
                if (!File.Exists(idm))
                {
                    MessageBox.Show("idm不存在！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                string url = "";
                string downpath = "";
                string filename = "";
                string ext = "";
                string status = "";

                foreach (DataGridViewRow row in dataGridView1.SelectedRows)
                {
                    status = row.Cells["ExtractorStatus"].Value.ToString();
                    if (status == ExtractorStatus.Sucess.GetDescription())
                    {
                        url = row.Cells["RealAddress"].Value.ToString();
                        downpath = Path.Combine(Service.Instance.DownPath, extractor.NovelName);
                        if (!Directory.Exists(downpath))
                        {
                            Directory.CreateDirectory(downpath);
                        }
                        ext = url.Substring(url.LastIndexOf("."));
                        filename = row.Cells["ChapterName"].Value.ToString() + ext;
                        args = $"/d {url} /p \"{downpath}\" /f \"{filename}\" /a";
                        Utils.RunExe(idm, args);
                    }
                }
                // 启动队列开始下载
                args = "/s";
                Utils.RunExe(idm, args);
            }
        }

        private async void MenuItem3_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                await extractor.ReExtractAudioLinksAsync(dataGridView1.SelectedRows);
                UpdateStatus();
            }
        }

        private async void btnRun_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                // 获取选中的第一个 ListViewItem
                ListViewItem selectedItem = listView1.SelectedItems[0];
                // 获取该行的第一个子项的文本（即第 0 列的数据）
                string novelName = selectedItem.SubItems[0].Text;
                string url = selectedItem.SubItems[3].Text;
                string siteName = selectedItem.SubItems[5].Text;

                extractor = extractors[siteName];

                novelData.Clear();
                btnRun.Enabled = false;
                btnDownByIdm.Enabled = false;
                btnSaveToFile.Enabled = false;
                pbRequestProcess.Minimum = 0;
                pbRequestProcess.Minimum = 0;
                pbRequestProcess.Value = 0;
                lblResult.Text = "";
                extractor._novelData = novelData;
                extractor._pbRequestProcess = pbRequestProcess;
                extractor._form = this;
                await extractor.ExtractAudioLinksAsync(novelName, url);

                this.UpdateStatus();

                //Util.PlayFinishedFile();
                MessageBox.Show("提取完成！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                btnRun.Enabled = true;
                btnDownByIdm.Enabled = true;
                btnSaveToFile.Enabled = true;
            }
        }

        private void 选项ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmSettings settings = new frmSettings();
            settings.ShowDialog();
        }

        private void miAbout_Click(object sender, EventArgs e)
        {
            frmAbout about = new frmAbout();
            about.ShowDialog();
        }

        private void miUsingHelp_Click(object sender, EventArgs e)
        {
            frmHelp help = new frmHelp();
            help.ShowDialog();
        }

        private void btnDownByIdm_Click(object sender, EventArgs e)
        {
            string idm = Service.Instance.IDMPath;
            string args = "";

            if (!File.Exists(idm))
            {
                MessageBox.Show("idm不存在！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 启动idm
            Utils.RunExe(idm, "");

            int ret = addTaskToIDM(idm);

            if (ret == 1)
            {
                // 启动队列开始下载
                args = "/s";
                Utils.RunExe(idm, args);
            }
        }

        private int addTaskToIDM(string idm)
        {
            string args = "";
            string url = "";
            string downpath = "";
            string filename = "";
            string ext = "";
            string status = "";

            // 添加到idm下载队列
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                status = row.Cells["ExtractorStatus"].Value.ToString();
                if (status == ExtractorStatus.Sucess.GetDescription())
                {
                    url = row.Cells["RealAddress"].Value.ToString();
                    downpath = Path.Combine(Service.Instance.DownPath, extractor.NovelName);
                    if (!Directory.Exists(downpath))
                    {
                        Directory.CreateDirectory(downpath);
                    }
                    ext = url.Substring(url.LastIndexOf("."));
                    filename = row.Cells["ChapterName"].Value.ToString() + ext;
                    args = $"/d {url} /p \"{downpath}\" /f \"{filename}\" /a";
                    Utils.RunExe(idm, args);
                }
                Thread.Sleep(300);
            }
            return 1;
        }

        private void UpdateStatus()
        {
            int total = Convert.ToInt32(dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["Index"].Value);

            int s = dataGridView1.Rows.Cast<DataGridViewRow>()
                .Count(row => row.Cells["ExtractorStatus"].Value.ToString() == ExtractorStatus.Sucess.GetDescription());

            int f = dataGridView1.Rows.Cast<DataGridViewRow>()
                 .Count(row => row.Cells["ExtractorStatus"].Value.ToString() == ExtractorStatus.Failure.GetDescription());

            lblResult.Text = $"共{total}集 成功：{s} 失败：{f}";
        }

        private void btnSaveToFile_Click(object sender, EventArgs e)
        {
            List<string> linesForDown = new List<string>();
            List<string> linesForRename = new List<string>();
            string ext;
            string downFile;
            string filename;
            string renameCmd;
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                string audioUrl = row.Cells["RealAddress"].Value.ToString();
                linesForDown.Add(audioUrl);

                downFile = audioUrl.Substring(audioUrl.LastIndexOf("/") + 1);
                ext = audioUrl.Substring(audioUrl.LastIndexOf("."));
                filename = row.Cells["ChapterName"].Value.ToString() + ext;
                renameCmd = $"rename \"{downFile}\" \"{filename}\"";
                linesForRename.Add(renameCmd);
            }

            string dir = Path.Combine(Service.Instance.DownPath, extractor.NovelName + "_地址文件");
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            // 拆分成1000条一个的list,并且每1000条保存成一个文件
            List<List<string>> chunks = Utils.SplitList(linesForDown, 1000);
            for (int i = 0; i < chunks.Count; i++)
            {
                Utils.WriteTextFile(Path.Combine(dir, $"{extractor.NovelName}_下载地址_{(i + 1).ToString().PadLeft(2, '0')}.txt"), chunks[i]);
            }
            // 保存重命名用bat文件
            Utils.WriteTextFile(Path.Combine(dir, $"{extractor.NovelName}_重命名.bat"), linesForRename);

            Process.Start("explorer.exe", dir);
        }

        private void InitializeDataTable()
        {
            // 创建 DataTable
            novelData = new DataTable();

            // 添加列
            novelData.Columns.Add("Index", typeof(string));
            novelData.Columns.Add("ChapterName", typeof(string));
            novelData.Columns.Add("ReqAddress", typeof(string));
            novelData.Columns.Add("RealAddress", typeof(string));
            novelData.Columns.Add("ExtractorStatus", typeof(string));

            // 将 DataTable 绑定到 DataGridView
            dataGridView1.DataSource = novelData;
            dataGridView1.Columns[0].Width = 70;
            dataGridView1.Columns[0].HeaderText = "序号";
            dataGridView1.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;

            dataGridView1.Columns[1].Width = 200;
            dataGridView1.Columns[1].HeaderText = "章节";
            dataGridView1.Columns[1].SortMode = DataGridViewColumnSortMode.NotSortable;

            dataGridView1.Columns[2].Width = 200;
            dataGridView1.Columns[2].HeaderText = "网页地址";
            dataGridView1.Columns[2].SortMode = DataGridViewColumnSortMode.NotSortable;

            dataGridView1.Columns[3].Width = 190;
            dataGridView1.Columns[3].HeaderText = "真实地址";
            dataGridView1.Columns[3].SortMode = DataGridViewColumnSortMode.NotSortable;

            dataGridView1.Columns[4].Width = dataGridView1.Width - 3 - dataGridView1.Columns[0].Width - dataGridView1.Columns[1].Width - dataGridView1.Columns[2].Width - dataGridView1.Columns[3].Width;
            dataGridView1.Columns[4].HeaderText = "状态";
            dataGridView1.Columns[4].SortMode = DataGridViewColumnSortMode.NotSortable;
        }

        private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (dataGridView1.Rows.Count == 0)
            {
                contextMenuStrip1.Items[0].Enabled = false;
                contextMenuStrip1.Items[1].Enabled = false;
                contextMenuStrip1.Items[2].Enabled = false;
            }
            else
            {
                contextMenuStrip1.Items[0].Enabled = true;
                contextMenuStrip1.Items[1].Enabled = true;
                contextMenuStrip1.Items[2].Enabled = true;
            }
        }

        private async void btnSearch_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            string keyword = txtKeyword.Text.Trim();
            if (keyword.Length == 0)
            {
                MessageBox.Show("关键字不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            try
            {
                List<SearchResultInfo> infos = new List<SearchResultInfo>();
                foreach (string key in extractors.Keys)
                {
                    var result = await extractors[key].Search("", keyword);
                    infos.AddRange(result);
                }

                if (infos.Count == 0)
                {
                    MessageBox.Show("没有找到", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    foreach (var info in infos)
                    {
                        if (listView1.InvokeRequired)
                        {
                            listView1.Invoke(new Action(() =>
                            {
                                ListViewItem item = new ListViewItem(info.NovelName);
                                item.SubItems.Add(info.NovelAuthor);
                                item.SubItems.Add(info.NovelAnchor);
                                item.SubItems.Add(info.NovelAddress);
                                item.SubItems.Add(info.Novelintro);
                                item.SubItems.Add(info.Site);
                                listView1.Items.Add(item);
                            }));
                        }
                        else
                        {
                            ListViewItem item = new ListViewItem(info.NovelName);
                            item.SubItems.Add(info.NovelAuthor);
                            item.SubItems.Add(info.NovelAnchor);
                            item.SubItems.Add(info.NovelAddress);
                            item.SubItems.Add(info.Novelintro);
                            item.SubItems.Add(info.Site);
                            listView1.Items.Add(item);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"查询时发生错误，请重试\r\n{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
